using System;
using FrameWork.BehaviourTree;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
using Sequence =  FrameWork.BehaviourTree.Sequence;

public class SlimeTree : FrameWork.BehaviourTree.Tree
{
    [SerializeField] private GameObject player;
    //
    public static readonly float slimeSpeed = 2f;
    public static readonly float slimeView = 6f;
    public static readonly float runAfterSpeed = 4f;

    
    
    private Vector2 leftPatrolPosition;
    private Vector2 rightPatrolPosition;

    private void OnEnable()
    {
        player = GameObject.FindGameObjectWithTag("Player");
    }

    /// <summary>
    /// 实现NPC生成接口
    /// 设定当前NPC边界
    /// </summary>
    /// <param name="leftPos">传入左边界</param>
    /// <param name="rightPos">传入右边界</param>
    public void Spawn(Vector3 leftPos, Vector3 rightPos)
    {
        leftPatrolPosition = leftPos;
        rightPatrolPosition = rightPos;
    }

    protected override Node SetupTree()
    {
        // 创建根节点
        Node root = new Selector(new List<Node>
        {
            // 顺序节点检测玩家是否在追击范围内
            new Sequence(new List<Node>
            {
                new CheckDistanceNode(transform, player),
                new MoveToPlayerNode(transform, player),
                new WaitNode(),
            }),
            // 巡逻
            new PatrolNode(leftPatrolPosition, rightPatrolPosition, transform),
        });

        return root;
    }
}

// 检测距离节点
public class CheckDistanceNode : Node
{
    private Transform _transform;
    private GameObject player;
    public CheckDistanceNode(Transform transform, GameObject player)
    {
        _transform = transform;
        this.player = player;
    }
    public override NodeState Evaluate()
    {
        if (Vector2.Distance(_transform.position, player.transform.position) < SlimeTree.slimeView)
        {
            state = NodeState.SUCCESS;
        }
        else
        {
            state = NodeState.FAILURE;
        }
        
        return state;
    }
}

// 移动到玩家节点
public class MoveToPlayerNode : Node
{
    private Transform _transform;
    private GameObject player;
    public MoveToPlayerNode(Transform transform, GameObject player)
    {
        _transform = transform;
        this.player = player;
    }
    public override NodeState Evaluate()
    {
        // 是否超出追击距离
        if (Vector3.Distance(_transform.position, player.transform.position) > 10f)
        {
            state = NodeState.FAILURE;
        }
        else
        {
            // 是否到达指定距离
            if (Vector3.Distance(_transform.position, player.transform.position) < 0.1f)
            {
                state = NodeState.SUCCESS;
            }
            else
            {
                // 没有超出追击距离也没有到达指定距离内
                _transform.position = Vector2.MoveTowards(_transform.position,player.transform.position, 
                    SlimeTree.runAfterSpeed * Time.deltaTime);
                state = NodeState.RUNNING;
            }
        }
        
        return state;
    }
}

// 等待节点
public class WaitNode : Node
{
    // 巡逻计时
    private float _waitCounter;              // 等待计时
    private float _waitingTime = 1f;         // 等待时间
    
    public override NodeState Evaluate()
    {
        // 空闲等待
        _waitCounter += Time.deltaTime;
        if (_waitCounter > _waitingTime)
        {
            _waitingTime = Random.Range(0.5f, 2f);
            state = NodeState.FAILURE;
        }
        else
        {
            state = NodeState.RUNNING;
        }
        return state;
    }
}

// 巡逻节点
public class PatrolNode : Node
{
    private Transform _transform;            // 组件
    private Vector2 leftPatrolPosition;
    private Vector2 rightPatrolPosition;
    
    // 巡逻计时
    private bool _isWaiting;                 // 是否等待
    private float _waitCounter;              // 等待计时
    private float _waitingTime = 1f;         // 等待时间
    
    private bool isCanSwitchTargetPosition = true;              // 是否可以更新新的目标位置
    private Vector3 targetPosition = Vector3.zero;

    /// <summary>
    /// 构造函数，设定巡逻边界
    /// </summary>
    /// <param name="leftPatrolPosition"></param>
    /// <param name="rightPatrolPosition"></param>
    public PatrolNode(Vector2 leftPatrolPosition, Vector2 rightPatrolPosition, Transform transform)
    {
        this.leftPatrolPosition = leftPatrolPosition;
        this.rightPatrolPosition = rightPatrolPosition;
        _transform = transform;
    }
    
    //
    public override NodeState Evaluate()
    {
        // 空闲等待
        if (_isWaiting)
        {
            _waitCounter += Time.deltaTime;
            if (_waitCounter > _waitingTime)
            {
                _isWaiting = false;
            }
        }
        else
        {
            // 随机游走
            _isWaiting = true;
            _waitingTime = Random.Range(1f, 2f);

            // 可以更新新的目标位置
            if (isCanSwitchTargetPosition)
            {
                targetPosition = new Vector3(Random.Range(leftPatrolPosition.x, rightPatrolPosition.x), 
                    Random.Range(leftPatrolPosition.y, rightPatrolPosition.y), 0f);
                isCanSwitchTargetPosition = false;
            }
            else
            {
                _transform.position = Vector3.MoveTowards(_transform.position, targetPosition, SlimeTree.slimeSpeed * Time.deltaTime);
                if(Vector3.Distance(_transform.position, targetPosition) < 0.1f)
                    isCanSwitchTargetPosition = true;
            }
        }
        // 返回状态，running，执行完继续执行
        state = NodeState.RUNNING;
        return state;
    }
}